﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form

    {
        int n = 0;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            disknumberCombobox.Focus();
            runButton.Enabled = false;
            resetButton.Enabled = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult des = MessageBox.Show("Are you sure?", "Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            if (des == DialogResult.Yes)
                Environment.Exit(0);
            else
                e.Cancel = true;
        }

        private void Create_Click(object sender, EventArgs e)
        {
            try
            {
                n = int.Parse(disknumberCombobox.Text);
                if (n > 1 && n < 11)
                {
                    processPanel.create(n);
                    stepstaken_Listview.Items.Add("Add disks sussesfully");
                    createButton.Enabled = false;
                    runButton.Enabled = true;
                    resetButton.Enabled = true;
                }
                else
                {
                    MessageBox.Show("Number of Disk error! Please try again", "", MessageBoxButtons.OK);
                    disknumberCombobox.Focus();
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Number of Disk error! Please try again", "", MessageBoxButtons.OK);
                disknumberCombobox.Focus();
            };

        }

        private void Run_Click(object sender, EventArgs e)
        {
            stepstaken_Listview.Items.Add("Start");
            runButton.Enabled = false;
            resetButton.Enabled = false;
            HaNoiTower('A', 'B', 'C');
            stepstaken_Listview.Items.Add("Finish");
            resetButton.Enabled = true;
            stepstaken_Listview.EnsureVisible(stepstaken_Listview.Items.Count - 1);
        }

        private void Reset_Click(object sender, EventArgs e)
        {
            processPanel.Controls.Clear();
            stepstaken_Listview.Items.Clear();
            disknumberCombobox.Text = "";
            createButton.Enabled = true;
            runButton.Enabled = false;
            resetButton.Enabled = false;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult des = MessageBox.Show("Are you sure?", "Exit",MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            if (des == DialogResult.Yes)
                Environment.Exit(0);            
        }

        private void infomationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 about = new AboutBox1();
            about.Show();
        }

        //////////////////////////////////////////////////////////////////////////////////////////

        private struct status
        {
            public int n;
            public int num;
            public char X, Y, Z;
            public status(int n, int num, char X, char Y, char Z)
            {
                this.n = n;
                this.num = num;
                this.X = X;
                this.Y = Y;
                this.Z = Z;
            }
        }
        private void Process(int diskNumber, char A, char B)
        {
            switch (A)
            {
                case 'A': processPanel.columnA.removedisk(processPanel.diskArray[n - diskNumber]);
                    break;
                case 'B': processPanel.columnB.removedisk(processPanel.diskArray[n - diskNumber]);
                    break;
                case 'C': processPanel.columnC.removedisk(processPanel.diskArray[n - diskNumber]);
                    break;
                default: break;
            }
            switch (B)
            {
                case 'A': processPanel.columnA.adddisk(processPanel.diskArray[n - diskNumber]);
                    break;
                case 'B': processPanel.columnB.adddisk(processPanel.diskArray[n - diskNumber]);
                    break;
                case 'C': processPanel.columnC.adddisk(processPanel.diskArray[n - diskNumber]);
                    break;
                default: break;
            }
            string text = "Move Disk from conlumn " + A + " to column " + B;
            stepstaken_Listview.Items.Add(text);
            stepstaken_Listview.EnsureVisible(stepstaken_Listview.Items.Count-1);
            System.Threading.Thread.Sleep(1000);
            System.Windows.Forms.Application.DoEvents();
        }
        public void HaNoiTower(char X, char Y, char Z)
        {
            if (n > 0)
            {
                Stack<status> st = new Stack<status>();
                status temp = new status(n, n, X, Y, Z);
                st.Push(temp);
                while (st.Count != 0)
                {
                    temp = st.Pop();
                    if (temp.num == 1)
                    {
                        Process(temp.n, temp.X, temp.Z);

                    }
                    else
                    {
                        status temp1 = new status(temp.n - 1, temp.n - 1, temp.Y, temp.X, temp.Z);
                        st.Push(temp1);
                        status temp2 = new status(temp.n, 1, temp.X, temp.Y, temp.Z);
                        st.Push(temp2);
                        status temp3 = new status(temp.n - 1, temp.n - 1, temp.X, temp.Z, temp.Y);
                        st.Push(temp3);
                    }
                }

            }
        }

    }

}
